package io.renren.modules.aic.service.impl;

import io.renren.common.exception.RRException;
import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.HttpContextUtils;
import io.renren.common.utils.IPUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.common.validator.Assert;
import io.renren.modules.aic.dao.MemberDao;
import io.renren.modules.aic.dao.MemberMachineDao;
import io.renren.modules.aic.entity.AccountingDto;
import io.renren.modules.aic.entity.CtocTransCountEntity;
import io.renren.modules.aic.entity.MachineEntity;
import io.renren.modules.aic.entity.MemberEntity;
import io.renren.modules.aic.entity.MemberMachineEntity;
import io.renren.modules.aic.entity.TeamEntity;
import io.renren.modules.aic.service.CtocTransCountService;
import io.renren.modules.aic.service.MachineService;
import io.renren.modules.aic.service.MemberService;
import io.renren.modules.aic.service.TeamService;
import io.renren.modules.aic.service.TokenService;
import io.renren.modules.sys.service.SysConfigService;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

	@Autowired
	TeamService teamService;

	@Autowired
	MemberDao memberDao;

	@Autowired
	MachineService machineService;

	@Autowired
	MemberMachineDao memberMachineDao;

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	CtocTransCountService ctocTransCountService;

	@Autowired
	TokenService tokenService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String mobile = (String) params.get("mobile");
		String authStatus = (String) params.get("authStatus");
		Page<MemberEntity> page = this.selectPage(new Query<MemberEntity>(params).getPage(), new EntityWrapper<MemberEntity>().eq(StringUtils.isNotBlank(mobile), "mobile", mobile)
				.eq(StringUtils.isNotBlank(authStatus), "auth_status", authStatus));

		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(MemberEntity member) {
		Assert.isTrue(this.selectCount(new EntityWrapper<MemberEntity>().eq("mobile", member.getMobile())) == 0, "手机号已注册");
		// sha256加密
		member.setSalt(RandomStringUtils.randomAlphanumeric(20));
		member.setPassword(DigestUtils.sha256Hex(member.getPassword() + member.getSalt()));
		if (StringUtils.isNotBlank(member.getPayword())) {
			member.setPayword(DigestUtils.sha256Hex(member.getPayword() + member.getSalt()));
		}
		member.setRecPerson(StringUtils.isNotBlank(member.getRecPerson()) ? member.getRecPerson().toUpperCase() : null);
		member.setCode(genCode());
		member.setRegIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
		member.setCreateTime(new Date());
		this.insert(member);

		// 处理上级推荐人
		if (StringUtils.isNotBlank(member.getRecPerson())) {
			MemberEntity m = this.selectOne(new EntityWrapper<MemberEntity>().eq("code", member.getRecPerson()));
			Assert.notNull(m, "推荐人无效");
			TeamEntity teamEntity = new TeamEntity();
			teamEntity.setMemberId(member.getId());
			teamEntity.setHigherOne(m.getId());
			TeamEntity t = teamService.selectOne(new EntityWrapper<TeamEntity>().eq("member_id", m.getId()));
			if (t != null) {
				if (t.getHigherOne() != null) {
					teamEntity.setHigherTwo(t.getHigherOne());
					if (t.getHigherTwo() != null) {
						teamEntity.setHigherThree(t.getHigherTwo());
					}
				}
			}
			teamService.insert(teamEntity);
		}
	}

	private String genCode() {
		String code = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
		if (this.selectCount(new EntityWrapper<MemberEntity>().eq("code", code)) > 0) {
			return genCode();
		}
		return code;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void changeStauts(String type, List<Long> memberIds) {
		Date now = new Date();

		if (type.equals("RZTG")) {

			// 认证通过
			for (Long memberId : memberIds) {
				MemberEntity member = new MemberEntity();
				member.setId(memberId);
				member.setUpdateTime(now);
				member.setAuthStatus(ProjectConstant.AUTH_STATUS_PASSED);
				this.updateById(member);

				// 认证通过赠送微型矿机
				if (sysConfigService.getValueI(ConfigConstant.AUTH_PASSED_GIVE_MACHINE) == ProjectConstant.COMMON_YES) {
					MachineEntity machine = machineService.selectById(1);
					MemberMachineEntity mm = new MemberMachineEntity();
					mm.setMemberId(member.getId());
					mm.setMachineNo("M" + DateUtils.format(new Date(), "yyyyMMddHH") + RandomStringUtils.randomNumeric(5));
					mm.setMachineName(machine.getMachineName());
					mm.setMachineType(machine.getMachineType());
					mm.setPrice(machine.getPrice());
					mm.setHashSecond(machine.getHashSecond());
					mm.setTotalDays(machine.getTotalDays());
					mm.setTotalProfit(machine.getTotalProfit());
					mm.setDayProfit(machine.getDayProfit());
					mm.setRunningDays(0);
					mm.setSumProfit(0d);
					mm.setPreProfit(0d);
					mm.setStatus(ProjectConstant.MACHINE_RUNSTATUS_RUNNING);
					mm.setIsReward(ProjectConstant.COMMON_YES);
					mm.setCreateTime(now);
					mm.setMachineImg(machine.getMachineImg());
					memberMachineDao.insert(mm);
				}
			}
		} else if (type.equals("RZSB")) {

			// 认证失败
			for (Long memberId : memberIds) {
				MemberEntity member = new MemberEntity();
				member.setId(memberId);
				member.setUpdateTime(now);

				member.setAuthStatus(ProjectConstant.AUTH_STATUS_FAILED);
				this.updateById(member);
			}
		} else if (type.equals("FH")) {

			// 封号
			for (Long memberId : memberIds) {
				MemberEntity member = new MemberEntity();
				member.setId(memberId);
				member.setUpdateTime(now);
				member.setStatus(ProjectConstant.COMMON_STATUS_DISABLE);
				this.updateById(member);

				// 移动端登录会话过期
				tokenService.expireToken(member.getId());
			}

		} else if (type.equals("JF")) {

			// 解封
			for (Long memberId : memberIds) {
				MemberEntity member = new MemberEntity();
				member.setId(memberId);
				member.setUpdateTime(now);
				member.setStatus(ProjectConstant.COMMON_STATUS_ENABLE);
				this.updateById(member);

				// 清除累计超时确认次数 否则定时任务又会自动封号
				CtocTransCountEntity ctocTransCount = new CtocTransCountEntity();
				ctocTransCount.setOrderUnconfirmed(0);
				ctocTransCount.setUpdateTime(now);
				ctocTransCountService.update(ctocTransCount, new EntityWrapper<CtocTransCountEntity>().eq("member_id", memberId));
			}

		} else {
			throw new RRException("操作失败[参数异常]");
		}

	}

	@Override
	public PageUtils selectMemberTeam(Map<String, Object> params) {
		Long id = Long.valueOf(params.get("id").toString());
		Integer level = Integer.valueOf(params.get("level").toString());
		Page<MemberEntity> page = new Query<MemberEntity>(params).getPage();
		page = page.setRecords(memberDao.selectMemberTeam(page, level, id));
		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void calcUserLevel(Set<Long> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return;
		}
		// 重新计算用户等级
		Date now = new Date();
		for (Long id : ids) {
			Double totalHashSecond = memberMachineDao.totalHashSecond(id);
			if (totalHashSecond != null && totalHashSecond >= sysConfigService.getValueD(ConfigConstant.MINER_LIMIT_NORMAL)) {
				// 体验矿工 to 普通矿工
				if (selectById(id).getUserLevel() == ProjectConstant.USER_LEVEL_INITIAL) {
					MemberEntity member = new MemberEntity();
					member.setId(id);
					member.setUserLevel(ProjectConstant.USER_LEVEL_NORMAL);
					member.setUpdateTime(now);
					this.updateById(member);
				}
			} else if (selectById(id).getUserLevel() == ProjectConstant.USER_LEVEL_NORMAL) {
				// 普通矿工 to 体验矿工
				MemberEntity member = new MemberEntity();
				member.setId(id);
				member.setUserLevel(ProjectConstant.USER_LEVEL_INITIAL);
				member.setUpdateTime(now);
				this.updateById(member);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void unblockAccount() {
		List<MemberEntity> list = this.selectList(new EntityWrapper<MemberEntity>().setSqlSelect("id", "blocked_time").eq("status", ProjectConstant.COMMON_STATUS_BLOCKED));
		if (CollectionUtils.isNotEmpty(list)) {
			Date now = new Date();
			for (MemberEntity memberEntity : list) {
				if (new Date().after(memberEntity.getBlockedTime())) {
					memberEntity.setStatus(ProjectConstant.COMMON_STATUS_ENABLE);
					this.updateById(memberEntity);

					// 矿机启动收益
					MemberMachineEntity memberMachine = new MemberMachineEntity();
					memberMachine.setStatus(ProjectConstant.MACHINE_RUNSTATUS_RUNNING);
					memberMachine.setUpdateTime(now);
					memberMachineDao.update(memberMachine,
							new EntityWrapper<MemberMachineEntity>().eq("status", ProjectConstant.MACHINE_RUNSTATUS_PAUSE).eq("member_id", memberEntity.getId()));
				}
			}
		}
	}

	@Override
	public Double totalBalance() {
		Double value = memberDao.totalBalance();
		return value == null ? 0 : value;
	}

	@Override
	public AccountingDto selectAccountingByMobile(String mobile) {
		return memberDao.selectAccountingByMobile(mobile);
	}

	@Override
	public PageUtils selectAccountingByHigher(Map<String, Object> params) {
		Long id = Long.valueOf(params.get("id").toString());
		Integer level = Integer.valueOf(params.get("level").toString());
		Page<AccountingDto> page = new Query<AccountingDto>(params).getPage();
		page = page.setRecords(memberDao.selectAccountingByHigher(page, level, id));
		return new PageUtils(page);
	}
}